/**
 * Copyright 2002 Cordys R&D B.V. 
 * 
 * This file is part of the Cordys .NET Connector. 
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 /**********************************************************************
Node Class Definition .Node class contains methods which can be used 
for Node manipulation on the current XML Document
**********************************************************************/


#include "windows.h"

#include "XmlForDotnet.h"
#include "Unmanaged.h"
#include "Managed.h"
#include "Node.h"

using namespace System;
using namespace System::Text;
using namespace com::eibus::xml::nom;

/*****************************************************************************************
	The following functions are managed Functions which are used to helper functions for
	the Node Class functions. These functions are for performing manipulation and for 
	fetching the Document elements.Manipulations like Add/Append/Insert/Rewrite/Delete/are
	performed on the Document Elements.
	For making the data that is allocated on the CLR's heap	available for the Unmanaged layer , the data is pinned. Pinning of the Data means ,
	the data that is allocated on CLR's heap should not be collected when GC is performing 
	garbage collection.And by releasing the pinned pointer, we are allowing the GC to 
	perform the garbage collection on this data also.
*****************************************************************************************/


/*****************************************************************************************
	#pragma managed is directive that should be used for making this function as an
	managed function. for defining the Unmanaged function " #pragma unmanaged " should 
	be used. until the aleternative directive is defined, the current directive applies
	to all the functions that are followed by this directive.
*****************************************************************************************/

#pragma managed
Int32 AddNode(Int32 from, Int32 to, Int32 dest)
{
	 return getXmlNodeId(xmlAdd(getXmlNode(from), getXmlNode(to), getXmlNode(dest)));
}

Int32 AppendNode(Int32 from, Int32 to, Int32 dest)
{
	 return getXmlNodeId(xmlAppend(getXmlNode(from), getXmlNode(to), getXmlNode(dest)));
}


int AppendToChildern(Int32 from, Int32 to, Int32 dest)
{
	 return getXmlNodeId(xmlAppendToChilds(getXmlNode(from), getXmlNode(to), getXmlNode(dest)));
}


int XmlDelete(Int32 from, Int32 to)
{
	 return (int) xmlDelete(getXmlNode(from), getXmlNode(to));
}

int XmlDuplicate(Int32 from, Int32 to)
{
	 return getXmlNodeId(xmlDuplicate(getXmlNode(from), getXmlNode(to)));
}

int  XmlDuplicateAndAdd(Int32 from ,Int32 to ,Int32 dest_element)
{
	return getXmlNodeId(xmlDuplicateAndAdd(getXmlNode(from), getXmlNode(to), getXmlNode(dest_element)));
}

int  XmlDuplicateAndAppend(Int32 from ,Int32 to ,Int32 dest_element)
{
	return getXmlNodeId(xmlDuplicateAndAppend(getXmlNode(from), getXmlNode(to), getXmlNode(dest_element)));
}

int  XmlDuplicateAndAppendToChild(Int32 from ,Int32 to ,Int32 dest_element)
{
	return getXmlNodeId(xmlDuplicateAndAppendToChilds(getXmlNode(from), getXmlNode(to), getXmlNode(dest_element)));
}

int  XmlDuplicateAndInsert(Int32 from ,Int32 to ,Int32 dest_element)
{
	return getXmlNodeId(xmlDuplicateAndInsert(getXmlNode(from), getXmlNode(to), getXmlNode(dest_element)));
}

int  XmlDuplicateAndInsertInChildren(Int32 from ,Int32 to ,Int32 dest_element)
{
	return getXmlNodeId(xmlDuplicateAndInsertInChilds(getXmlNode(from), getXmlNode(to), getXmlNode(dest_element)));
}

String __gc * XmlGetAttribute(Int32 node, String __gc * name)
{	
	Byte __pin * pbytes = GetUTF8CharForStr(name);
	const char* value = (char*) xmlGetAttributeHandle(getXmlNode(node), (tChar*) pbytes);
	if (value)
	{	
		ReleasePINPointer(pbytes);
		//return new String(value);
		return new String(value, 0, strlen(value), Encoding::UTF8);
	}
	ReleasePINPointer(pbytes);
	return NULL;
}

String __gc * XmlGetAttributeName(Int32 node , Int32 index)
{
	const char* name = (char*) xmlGetAttributeNameHandle(getXmlNode(node), index);
	if (name)
	{
		//return new String(name);
		return new String(name, 0, strlen(name), Encoding::UTF8);
	}
	return NULL;
}

String __gc * XmlGetAttributeNameSpaceURI(Int32 node , Int32 index)
{
	const char* namespaceURI = (char*) xmlGetAttributeNamespaceURIHandle(getXmlNode(node), (int) index);
	if (namespaceURI)
	{
		//return new String(namespaceURI);
		return new String(namespaceURI, 0, strlen(namespaceURI), Encoding::UTF8);
	}
	return NULL;
}

//Check it out properly whether the array prefix is filled properly are not
//***********************************************************************
String __gc * XmlGetAttributePrefix(Int32 node , Int32 index)
{
	Byte prefix __gc[] = new Byte __gc[1024];
	Byte __pin * pbytes = &prefix[0];

	if(UMXmlAttrPrefix(node,index,pbytes))
	{
		ReleasePINPointer(pbytes);
		return GetUTF8String(prefix);
	}
	else
	{
		ReleasePINPointer(pbytes);
		return NULL;
	}
}

Int32 XmlGetCompoundType(Int32 node)
{
	return xmlGetCt(getXmlNode(node));
}

String __gc * XmlGetData(Int32 node , String __gc * defaultValue)
{	
	bool virtualAlloc = false;
	String * dataString = defaultValue;
	
	char*  dataChar = UMXmlGetData(node,&virtualAlloc);
	if(dataChar)
	{
		//dataString = new String((char*)dataChar);		
		dataString = new String(dataChar, 0, strlen(dataChar), Encoding::UTF8);
		
		// Release the memory that is allocated in the UMDataToCharArray method
		if ( virtualAlloc )	{	
			VirtualFree(dataChar, 0, MEM_RELEASE);	
		}
		else
		{
			if(dataChar)
			{	
				delete dataChar;
			}
		}
	}
	return dataString;
}

String __gc * XmlGetDataElement(Int32 node ,String __gc * tagName, String __gc * defaultValue)
{
	Byte __pin *tagBytes = GetUTF8CharForStr(tagName);
	bool virtualAlloc = false;
	String* dataElementString = defaultValue;

	char* unmanagedData = (char*)UMXmlGetDataElement(node, tagBytes, &virtualAlloc);
	if(unmanagedData)
	{
		//String* dataElementString = new String(unmanagedData);	
		String* dataElementString = new String(unmanagedData, 0, strlen(unmanagedData), Encoding::UTF8);
		// Release the memory that is allocated in the unmanaged heap inside UMDataToCharArray method
		if ( virtualAlloc )	{
			VirtualFree(unmanagedData, 0, MEM_RELEASE);
		}
		else
		{	
			delete unmanagedData;
		}
	}

	ReleasePINPointer(tagBytes); 
	return dataElementString;
}

// New for BP
String __gc * XmlGetDataElementNS(Int32 node, String __gc * tagName, String __gc * uri, String __gc * defaultValue)
{
	Byte __pin *tagBytes = GetUTF8CharForStr(tagName);

	Byte __pin * uriBytes;
	if(uri)
		uriBytes = GetUTF8CharForStr(uri);

	bool virtualAlloc = false;
	String* dataElementString = defaultValue;

	char* unmanagedData = (char*)UMXmlGetDataElementNS(node, tagBytes, uriBytes, &virtualAlloc);
	if(unmanagedData)
	{
		//String* dataElementString = new String(unmanagedData);	
		String* dataElementString = new String(unmanagedData, 0, strlen(unmanagedData), Encoding::UTF8);
		// Release the memory that is allocated in the unmanaged heap inside UMDataToCharArray method
		if ( virtualAlloc )	{
			VirtualFree(unmanagedData, 0, MEM_RELEASE);
		}
		else
		{	
			delete unmanagedData;
		}
	}

	ReleasePINPointer(tagBytes); 
	if(uri)
		ReleasePINPointer(uriBytes); 
	return dataElementString;
}

Int32 XmlGetDataType(Int32 node)
{
	return (Int32) xmlGetDt(getXmlNode(node));
}

Int32 XmlGetDocID(Int32 node)
{
	return (Int32)getXmlDocId(xmlGetDoc(getXmlNode(node)));
}

Int32 XmlGetElement(Int32 node, String __gc * tagName)
{
	Byte __pin * pbytes = GetUTF8CharForStr(tagName);
	return (Int32)getXmlNodeId(xmlGetElement(getXmlNode(node), (tChar*)pbytes));
}

// New for BP
Int32 XmlGetElementNS(Int32 node, String __gc * tagName, String __gc * uri)
{
	Byte __pin * pbytes = GetUTF8CharForStr(tagName);
	Byte __pin * pbytesUri = GetUTF8CharForStr(uri);
	return (Int32)getXmlNodeId(xmlGetElementNS(getXmlNode(node), (tChar*)pbytes, (tChar*)pbytesUri));
}

Int32 XmlGetFirstChild(Int32 node)
{
	return (Int32)getXmlNodeId(xmlGetFChild(getXmlNode(node)));
}

Int32 XmlGetFirstChildElement(Int32 node)
{
	return (Int32)getXmlNodeId(xmlGetElementFChild(getXmlNode(node)));
}

Int32 XmlGetLastChild(Int32 node)
{
	return (Int32)getXmlNodeId(xmlGetLChild(getXmlNode(node)));
}

Int32 XmlGetLastChildElement(Int32 node)
{
	return (Int32)getXmlNodeId(xmlGetElementLChild(getXmlNode(node)));
}

String __gc * XmlGetLocalName(Int32 node)
{
	const char* name = (char*) xmlGetLocalNameHandle(getXmlNode(node));
	if (name)
	{
		//return new String(name);
		return new String(name, 0, strlen(name), Encoding::UTF8);
	}
	else
	{
		return NULL;
	}
}

String __gc * XmlGetName(Int32 node)
{
	const char* localName = (char*) xmlGetNameHandle(getXmlNode(node));
	if (localName)
	{
		//return new String(localName);
		return new String(localName, 0, strlen(localName), Encoding::UTF8);
	}
	else
	{
		return NULL;
	}
}

String __gc * XmlGetNameSpaceURI(Int32 node)
{
	const char* uri = (char*) xmlGetNamespaceURIHandle(getXmlNode(node));
	if (uri)
	{
		//return new String(uri);
		return new String(uri, 0, strlen(uri), Encoding::UTF8);
	}
	else
	{
		return NULL;
	}
}

Int32 XmlGetNextSibling(Int32 node)
{
	return (Int32)getXmlNodeId(xmlGetRSib(getXmlNode(node)));
}

Int32 XmlGetNextElement(Int32 node)
{
	return (Int32)getXmlNodeId(xmlGetElementRSib(getXmlNode(node)));
}

Int32 XmlGetNumAttr(Int32 node)
{
	return (Int32) xmlGetNumAttributes(getXmlNode(node));
}

Int32 XmlGetNumChildren(Int32 node)
{
	return (Int32) xmlGetNumChilds(getXmlNode(node));
}

Int32 XmlGetNumChildElements(Int32 node)
{
	return (Int32) xmlGetNumChildElements(getXmlNode(node));
}

Int32 XmlGetNumNextSiblings(Int32 node)
{
	return (Int32) xmlGetNumRSib(getXmlNode(node));
}

Int32 XmlGetNumPreviousSiblings(Int32 node)
{
	return (Int32) xmlGetNumLSib(getXmlNode(node));
}

Int32 XmlGetNumSiblings(Int32 node)
{
	return (Int32) xmlGetNumSib(getXmlNode(node));
}

Int32 XmlGetParent(Int32 node)
{
	return (Int32) getXmlNodeId(xmlGetParent(getXmlNode(node)));
}

Int32 XmlGetPrevSib(Int32 node)
{
	return (Int32)getXmlNodeId(xmlGetLSib(getXmlNode(node)));
}

Int32 XmlGetPrevElement(Int32 node)
{
	return (Int32)getXmlNodeId(xmlGetElementLSib(getXmlNode(node)));
}

Int32 XmlGetRoot(Int32 node)
{
	return (Int32)getXmlNodeId(xmlGetRoot(getXmlNode(node)));
}

Int32 XmlGetType(Int32 node)
{
	return (Int32)xmlGetType(getXmlNode(node));
}

Int32 XmlInsert(Int32 from,Int32 to,Int32 dest)
{
	return getXmlNodeId(xmlInsert(getXmlNode(from), getXmlNode(to), getXmlNode(dest)));
}

Int32 XmlInsertInChildren(Int32 from,Int32 to,Int32 dest)
{
	return getXmlNodeId(xmlInsertInChilds(getXmlNode(from), getXmlNode(to), getXmlNode(dest)));
}

Int32 XmlRemoveAttribute(Int32 node , String __gc * tagName)
{
	Byte __pin * pbytes = GetUTF8CharForStr(tagName);
	Int32 res = (Int32)xmlDeleteAttribute(getXmlNode(node), (tChar*) pbytes);
	ReleasePINPointer(pbytes); 
	return res;
}

Int32 XmlSetAttribute(Int32 node,String __gc * tagName ,String __gc * tagValue)
{
	Byte __pin * tbytes;
	Byte __pin * vbytes;

	if (tagName)
		tbytes = GetUTF8CharForStr(tagName);

	if (tagValue)
		vbytes = GetUTF8CharForStr(tagValue);

	int res = xmlSetAttribute(getXmlNode(node), (tChar*) tbytes, (tChar*) vbytes);

	if (tagName)
		ReleasePINPointer(tbytes); 

	if (tagValue)
		ReleasePINPointer(vbytes);

	return (Int32) res;
}

Int32 XmlSetData(Int32 node , String __gc * data)
{
	Byte __pin * dataBytes;

	if(data)
		dataBytes = GetUTF8CharForStr(data);
	
	Int32 res = (Int32) xmlSetData(getXmlNode(node), (tChar*) dataBytes);

	if(data)
		ReleasePINPointer(dataBytes);
	return res;
}

Int32 XmlSetDataElement(Int32 node ,String __gc * dataElement , String __gc * data)
{
	Byte __pin * dataElementBytes;
	Byte __pin * dataBytes;

	if(dataElement)
		dataElementBytes = GetUTF8CharForStr(dataElement);

	if(data)
		dataBytes = GetUTF8CharForStr(data);

	Int32 res = xmlSetDataElement(getXmlNode(node), (tChar*) dataElementBytes, (tChar*) dataBytes);

	if(dataElement)
		ReleasePINPointer(dataElementBytes);

	if(data)
		ReleasePINPointer(dataBytes);
	return res;
}

Int32 XmlSetName(Int32 node , String __gc * name)
{
	Byte __pin * nameBytes;

	if(name)
		nameBytes = GetUTF8CharForStr(name);

	Int32 res = (Int32) xmlSetName(getXmlNode(node), (tChar*) nameBytes);

	if(name)
		ReleasePINPointer(nameBytes);
	return res;
}

Int32 XmlUnlink(Int32 fromNode ,Int32 toNode)
{	
	return getXmlNodeId(xmlUnlink(getXmlNode(fromNode), getXmlNode(toNode)));
}


/*
Byte XmlWriteToByteArray(Int32 fromNode, Int32 toNode, Int32 pretty) __gc[]
{	
	const char * strBuff = (const char *)UMXmlWriteToByteArray(fromNode,toNode,pretty);
	String * str = new String(strBuff);		
	Byte   dataBytes __gc[] = GetByteFromStr(str);	
	return dataBytes;
}

Byte XmlWriteToByteArray1(Int32 fromNode, Int32 toNode, Int32 pretty) __gc[]
{	
	const char * strBuff = (const char *)UMXmlWriteToByteArray(fromNode,toNode,pretty);
	String * str = new String(strBuff);
	//Console::Write("String in XmlWriteByt   :");
	//Console::WriteLine(str);
	Byte   dataBytes __gc[] = GetByteFromStr(str);	
	return dataBytes;
}*/

Byte XmlWriteToByteArray(Int32 fromNode, Int32 toNode, Int32 pretty) __gc[]
{
	tHGstDoc stream;
	Byte   dataBytes __gc[]= NULL ;

	if ( (stream = xjaGetInMemoryStream()) )
	{
		gstSetLocation(stream, 0);

		int streamLength = UMXmlWriteToStream(fromNode,toNode,pretty,stream);
		const char* internalBytes  = (const char*) gstGetHandle(stream);		
		dataBytes = new Byte[streamLength];
		if(dataBytes!=NULL)
		{
			GetByteFromChar(internalBytes,dataBytes,streamLength);
		}
		//dataBytes = GetByteFromStr(str);
		xjaReleaseInMemoryStream();
	}
	return dataBytes;
}

void XmlWriteToFile(Int32 fromNode ,Int32 toNode, String __gc * fileName , Int32 pretty)
{
	Byte __pin * pbytes;
	try
	{
		pbytes = GetUTF8CharForStr(fileName);
		UMWriteToFile(fromNode,toNode,pbytes,pretty);
	}
	catch(const char* exString)
	{
		throw new XMLException(new String(exString));
	}
	__finally
	{
		ReleasePINPointer(pbytes);
	}
}


/******************************************************************************************
	Node Class Implementation. Node class contains static methods through which on 
	xml manipulations like traversing through nodes, adding ,appending, deleting the xml 
	elements can be performed.
******************************************************************************************/

/*
*  Adds the specified node to the destination node (i.e. the node
*  added will be the immediate right sibling)
* @param node int reference of the node
* @param dest int reference of the node in which to insert
*/
Int32 Node::Add(Int32 node, Int32 dest_element)
	{	
		return AddNode(node, node, dest_element);
	}

/** Adds a range of nodes to the destination node (i.e. they
 * will be the immediate right siblings)
 *@param from int reference of the node
 *@param to If from and to aresame only that node will be inserted if to is specified as 0 all siblings will be inserted
 *@param dest int reference of the node in which to insert
 */
Int32 Node::Add(Int32 fromNode, Int32 toNode ,Int32 dest_element)
	{
		return AddNode(fromNode, toNode, dest_element);
	}

/** Appends a range of nodes to most right sibling of 
 * the destination node.
 *@param node int reference of the node
 *@param dest int reference of the node in which to append
*/
Int32 Node::Append(Int32 node, Int32 dest_element)
	{
		return AppendNode(node, node, dest_element);
	}

/** Appends a range of nodes to most right sibling of 
 * the destination node.
 *@param from int reference of the node
 *@param to If from and to aresame only that node will be appended if to is specified as 0 all siblings will be appended
 *@param dest int reference of the node in which to append
*/
Int32 Node::Append(Int32 fromNode, Int32 toNode, Int32 dest_element)
	{
		return AppendNode(fromNode, toNode, dest_element);
	}

/** Appends the specified node to the children of the destination node
 *@param node int reference of the node
 *@param dest int reference of the node in which to insert
 */
Int32 Node::AppendToChild(Int32 node, Int32 dest_element)
	{
		return AppendToChildern(node, node, dest_element);
	}

/** Appends the specified node to the children of the destination node
 *@param node int reference of the node
 *@param to If from and to aresame only that node will be inserted if to is specified as 0 all siblings will be inserted
 *@param dest int reference of the node in which to insert
 */
Int32 Node::AppendToChild(Int32 fromNode, Int32 toNode, Int32 dest_element)
	{
		return AppendToChildern(fromNode, toNode, dest_element);
	}

/** Deletes the Node and its children
 *@param node int reference of the node
 */
Int32 Node::Delete(Int32 node )
	{
		return XmlDelete(node, node);
	}

/** Deletes the range of Nodes from the specified fromNode reference to the  toNode reference
 * @param from node int reference of the node
 * @param to node int reference of the node
 */
Int32 Node::Delete(Int32 fromNode, Int32 toNode )
	{
		return XmlDelete(fromNode, toNode);
	}


/** Duplicates the specified node
 *@param node int reference of node which is to be duplicated
 */
Int32 Node::Duplicate(Int32 node)
	{
		return XmlDuplicate(node , node);
	}

/** Duplicates a range of nodes
 *@param from int reference of node from which to duplicate
 *@param to int reference of the node to which to duplicate
*/
Int32 Node::Duplicate(Int32 fromNode, Int32 toNode )
	{
		return XmlDuplicate(fromNode , toNode);
	}

/** Duplicates and adds a range of nodes to the destination node (i.e. they
 * will be the immediate right siblings)
 *@param from int reference of the node which is to be duplicated and inserted
 *@param to If from and to are same only that node will be duplicated and inserted if to is specified as 0 all siblings will be duplicated and inserted
 *@param dest int reference of the node in which to insert
 */
Int32 Node::DuplicateAndAdd(Int32 fromNode, Int32 toNode , Int32 dest_element )
	{
		return XmlDuplicateAndAdd(fromNode , toNode , dest_element);
	}


/** Duplicates and appends a range of nodes to most right sibling of 
* the destination node.
*@param from int reference of the node which is to be duplicated
*@param to If from and to are same only that node will be duplicated and appended if to is specified as 0 all siblings will be duplicated and appended
*@param dest int reference of the node in which to append
*/
Int32 Node::DuplicateAndAppend(Int32 fromNode, Int32 toNode , Int32 dest_element )
	{
		return XmlDuplicateAndAppend(fromNode , toNode , dest_element);
	}

/** Duplicates and appends the range of nodes to the children of the destination node
*@param from int reference of the node which is to be duplicated
*@param to If from and to aresame only that node will be duplicated and appended if to is specified as 0 all siblings will be duplicated and appended
*@param dest int reference of the node in which to insert
*/
Int32 Node::DuplicateAndAppendToChildren(Int32 fromNode, Int32 toNode , Int32 dest_element )
	{
		return XmlDuplicateAndAppendToChild(fromNode , toNode , dest_element);
	}


/** Duplicates and inserts a range of nodes into the destination node (i.e.
* they will be the immediate left siblings)
*@param from int reference of the node from which to duplicate
*@param to If from and to are same only that node will be duplicated and inserted if to is specified as 0 all siblings will be duplicated and inserted
*@param dest int reference of the node in which to insert
*/
Int32 Node::DuplicateAndInsert(Int32 fromNode, Int32 toNode , Int32 dest_element )
	{
		return XmlDuplicateAndInsert(fromNode , toNode , dest_element);
	}

/** Duplicates and inserts the range of nodes into the children of the destination node
* (i.e. the range will be the set of left siblings of the first child of
* the destination node).
*@param from int reference of the node which is to be duplicated
*@param to If from and to are same only that node will be duplicated and inserted if to is specified as 0 all siblings will be duplicated and inserted
*@param dest int reference of the node in which to insert
*/
Int32 Node::DuplicateAndInsertinChildren(Int32 fromNode, Int32 toNode , Int32 dest_element )
	{
		return XmlDuplicateAndInsertInChildren(fromNode , toNode , dest_element);
	}

/** Returns the value of the attribute with the specified name in the node,
 * if the node is of type Element
 * @param int Node reference 
 * @param AttributeName in the Node
 */
String* Node::GetAttribute(int node, String* attributeName)
	{
		return XmlGetAttribute(node,attributeName);
	}

/** Returns the value of the attribute with the specified name in the node,if not 
 * found then return the default value.
 * if the node is of type Element
 * @param int Node reference
 * @param AttributeName in the Node
 * @param default value that if attributename not found
 */
String* Node::GetAttribute(int node, String* attributeName , String* defaultValue)
	{
		String* value = XmlGetAttribute(node,attributeName);
		if(value == NULL)
		{
			value = defaultValue;
		}
		return value;
	}

/** Returns the name of the attribute with the specified index in the node
 * @param int Node reference
 * @param Attribute's index in the Node
 */
String* Node::GetAttributeName(Int32 node , Int32 index)
		{
		return XmlGetAttributeName(node,index);
		}

/** Returns the expanded namespace of the attribute with the specified index in the node
 * @param int Node reference
 * @param Attribute's index in the Node
 */
String* Node::GetAttributeNameSpaceURI(Int32 node , Int32 index)
		{
		return XmlGetAttributeNameSpaceURI(node,index);
		}

/** Returns the namespace prefix of the attribute with the specified index in the node
 * @param int Node reference
 * @param Attribute's index in the Node
 */
String* Node::GetAttributePrefix(Int32 node , Int32 index)
		{
		return XmlGetAttributePrefix(node,index);
		}

/** Returns the compound type of the node 
 * @see com.eibus.xml.nom.CompoundType
 */
Int32 Node::GetCompoundType(int node)
		{
			return XmlGetCompoundType(node);
		}

/** Returns the data in the node, if it is of type Text, otherwise collects all data
 * of all children nodes and returns that. 
 * @return The data of the node or its children, or the default value.
 */
String* Node::GetData(int node)
	{
		return XmlGetData(node,"0");
	}

/** Returns the data in the node, if it is of type Text, otherwise collects all data
 * of all children nodes and returns that. If there is no data in the node or its children,
 * the defaultValue is returned.
 * @return The data of the node or its children, or the default value.
 */
String* Node::GetData(int node, String* defaultValue)
	{
		return XmlGetData(node,defaultValue);
	}

String* Node::GetDataElement(Int32 node, String* tagName, String* defaultValue)
	{
		return XmlGetDataElement(node, tagName, defaultValue);
	}

// New for BP
String* Node::GetDataElementNS(Int32 node, String* tagName, String* uri, String* defaultValue)
	{
		return XmlGetDataElementNS(node, tagName, uri, defaultValue);
	}

//---------------------------
//public : static String __gc * GetDataOfFirstChildElement(); 

/** Returns the datatype of the node 
 * @see com.eibus.xml.nom.DataType
 */
Int32 Node::GetDataType(Int32 node)
	{
		return XmlGetDataType(node);
	}

/** Returns a Document object to which the node belongs, or null if there is no
* document
* @param The node to retrieve the document from
* @return The Document.
*/
Document* Node::GetDocument(Int32 node)
	{	
		Int32 doc_id = XmlGetDocID(node);		
		if(doc_id)
		{
			return new Document(doc_id);
		}
		else
		{
			return NULL;
		}
	}
	
/*
 * Returns the first element child node of the given node with the given tagName.
 */
Int32 Node::GetElement(Int32 node, String* tagName)
	{
		return XmlGetElement(node, tagName);
	}

/*
 * Returns the first element child node of the given node with the given tagName.
 */
// New for BP
Int32 Node::GetElementNS(Int32 node, String* tagName, String* uri)
	{
		return XmlGetElementNS(node, tagName, uri);
	}

/*
 * Returns the First data child of the Node.
 */
Int32 Node::GetFirstChild(Int32 node)
	{
		return XmlGetFirstChild(node);
	}
	
/*
 * Returns the First data child element of the Node.
 */
Int32 Node::GetFirstChildElement(Int32 node)
	{
		return XmlGetFirstChildElement(node);
	}

/** Returns the first child of node that is of type data
* @param node The node to retrieve the first data child from
* @return The pointer to the first data node, or 0 if the node has
* no data child.
*/
Int32 Node::GetFirstDataNode(Int32 node)
	{
		int child = GetFirstChildElement(node);
			while (child != 0)
				{
					if (GetNodeType(child) == NodeType::ELEMENT)
						return child;
					child = GetNextElement(child);
				}
			return 0;
	}

/** Returns the first child of node that is of type element
* @param node The node to retrieve the first element child from
* @return The pointer to the first element node, or 0 if the node has
* no element child.
*/
Int32 Node::GetFirstElement(Int32 node)
	{
		int child = GetFirstChildElement(node);
		while (child != 0)
			{
				if (GetNodeType(child) == NodeType::ELEMENT)
					return child;
				child = GetNextElement(child);
			}
		return 0;						
	}

/* Returns the Last child of the Node
 *@param Node reference 
 */
Int32 Node::GetLastChild(Int32 node)
	{
		return XmlGetLastChild(node);
	}

/* Returns the Last child element of the Node
 *@param Node reference 
 */
Int32 Node::GetLastChildElement(Int32 node)
	{
		return XmlGetLastChildElement(node);
	}

/** Returns the local name of the node. This is the part of the tagname
 * that follows the first colon.
 *@param Node reference 
 */
String* Node::GetLocalName(Int32 node)
	{
		return XmlGetLocalName(node);
	}

/* Returns the  name of the Node reference
 *@param Node reference 
 */
String* Node::GetName(Int32 node)
	{
		return XmlGetName(node);
	}

/* Returns the  URI specified for the Node reference
 *@param Node reference 
 */
String* Node::GetNameSpaceURI(Int32 node)
	{
		return XmlGetNameSpaceURI(node);
	}

/** Returns the next (right) sibling of the node
 * @param Node reference 
 */
Int32 Node::GetNextSibling(Int32 node)
	{
		return XmlGetNextSibling(node);
	}

/** Returns the next (right) sibling element of the node
 * @param Node reference 
 */
Int32 Node::GetNextElement(Int32 node)
	{
		return XmlGetNextElement(node);
	}

/** Returns the number of attributes in the node, if it is of type element
 *  @param Node reference 
 */
Int32 Node::GetNumAttributes(Int32 node)
	{
		return XmlGetNumAttr(node);
	}

/** Returns the number of Children of the node
 *  @param Node reference 
 */
Int32 Node::GetNumChildren(Int32 node)
	{
		return XmlGetNumChildren(node);
	}

/** Returns the number of Children of the node
 *  @param Node reference 
 */
Int32 Node::GetNumChildElements(Int32 node)
	{
		return XmlGetNumChildElements(node);
	}

/** Returns the number of siblings next to (on the right of) the node
 *  @param Node reference 
 */
Int32 Node::GetNumNextSiblings(Int32 node)
	{
		return XmlGetNumNextSiblings(node);
	}

/** Returns the number of siblings previous to (on the left of) the node
 *  @param Node reference 
 */
Int32 Node::GetNumPreviousSiblings(Int32 node)
	{
		return XmlGetNumPreviousSiblings(node);
	}

/** Returns the number of siblings of the node
 *  @param Node reference 
 */
Int32 Node::GetNumSiblings(Int32 node)
	{
		return XmlGetNumSiblings(node);
	}

/** Returns the parent node of the node
 *  @param Node reference 
 */
Int32 Node::GetParent(Int32 node)
	{
		return XmlGetParent(node);
	}

/** Returns the prefix of the tag name of the element. This is the part of the 
 * tagname before the first colon.
 *  @param Node reference
 */
String* Node::GetPrefix(Int32 node)
	{
		return XmlGetName(node);
	}

/** Returns the previous (left) sibling of the node
 *  @param Node reference
 */
Int32 Node::GetPreviousSibling(Int32 node)
	{
		return XmlGetPrevSib(node);
	}

/** Returns the previous (left) sibling element of the node
 *  @param Node reference
 */
Int32 Node::GetPreviousElement(Int32 node)
	{
		return XmlGetPrevElement(node);
	}

/** Returns the root node of the node.
 *  @param Node reference
 */
Int32 Node::GetRoot(Int32 node)
	{
		return XmlGetRoot(node);
	}

/** Returns the type of the node 
 *  @param Node reference
 */
Int32 Node::GetNodeType(Int32 node)
	{
		return XmlGetType(node);
	}



/** Inserts Node to the destination node (i.e.
 * that node be the immediate left sibling)
 *@param from int reference of the node 
 *@param dest int reference of the node in which to insert
 */
Int32 Node::Insert(Int32 node, Int32 nodedest)
	{
		return XmlInsert(node,node,nodedest);
	}

/** Inserts a range of nodes into the destination node (i.e.
 * they will be the immediate left siblings)
 *@param nodefrom int reference of the node
 *@param nodeto If from and to aresame only that node will be inserted if to is specified as 0 all siblings will be inserted
 *@param nodedest int reference of the node in which to insert
 */
Int32 Node::Insert(Int32 nodefrom, Int32 nodeto, Int32 nodedest)
	{
		return XmlInsert(nodefrom,nodeto,nodedest);
	}

/** Inserts the range of nodes into the children of the destination node
 * (i.e. the range will be the set of left siblings of the first child of
 * the destination node).
 * @param nodefrom int reference of the node
 * @param nodeto If from and to aresame only that node will be inserted if to is specified as 0 all siblings will be inserted
 * @param nodedest int reference of the node in which to insert
*/
Int32 Node::InsertInChildren(Int32 nodefrom, Int32 nodeto, Int32 nodedest)
	{
		return XmlInsertInChildren(nodefrom,nodeto,nodedest);
	}

/** Removes the attribute with the specified name in the node, and returns
 * the result of this action (0 if succeeded).
 */
Int32 Node::RemoveAttribute(Int32 nodefrom, String* tagName)
	{
		return XmlRemoveAttribute(nodefrom, tagName);
	}

/** Sets the attribute in the node, if it is of type element
 * @param node int reference of the node
 * @param tagName name of the attribute
 * @param tagValue value for the attribute
 */
void Node::SetAttribute(Int32 node,String* tagName ,String* tagValue)
	{
			XmlSetAttribute(node,tagName,tagValue);
	}

/** Sets the data in the node, if it is of type Text
 * @param node int reference of the node
 * @param data value for the TextElement
 */
void Node::SetData(Int32 node,String* data)
	{
			XmlSetData(node,data);
	}
/** Rewrites the data children of the elements that are a child of node
 * that have tag as tagname.
 * @param node int reference of the node
 * @param tagName name of the Element
 * @param data value to replace
*/
void Node::SetDataElement(Int32 node,String __gc * tagName, String __gc * data)
	{
			XmlSetDataElement(node,tagName,data);
	}

/** Sets the Document refernce 
 * This is to hold the document object by preventing it to garbage collected.
 * @param doc reference Of the Document
 */
void Node::SetDocument(Document* doc)
	{
		doc_ref = doc;
	}

/** Sets the tagname of the node, if it is of type element
 * @param node int reference of the node
 * @param tagName name of the Element 
*/
void Node::SetName(Int32 node, String __gc * tagName)
	{
		XmlSetName(node , tagName);
	}

/** Unlinks a range of nodes from the tree they are in
*/
void Node::Unlink(Int32 node)
	{
		XmlUnlink(node,node);
	}

/** Unlinks a range of nodes from the tree they are in
*/
void Node::Unlink(Int32 node, Int32 to)
	{
		XmlUnlink(node , to);
	}

/** Writes the contents of the node into the byte-array that is returned
 *@param node int reference of the node 
 *@pretty pretty 1 to write with indentation 0 without indentation 
 */
Byte Node::WriteToByteArray(Int32 node, bool pretty) __gc[]
	{
		if(pretty)
		{
			return XmlWriteToByteArray(node,node,WRITE_PRETTY);
		}
		else
		{
			return XmlWriteToByteArray(node,node,WRITE_NORMAL);
		}								
	}

/** Writes the contents of the node into the byte-array that is returned
*@param fromNode int reference of the node
*@param toNode until which node
*@pretty pretty 1 to write with indentation 0 without indentation 
*/
Byte Node::WriteToByteArray(Int32 fromNode ,Int32 toNode ,bool pretty) __gc[]
	{
		if(pretty)
		{
			return XmlWriteToByteArray(fromNode,toNode,WRITE_PRETTY);
		}
		else
		{
			return XmlWriteToByteArray(fromNode,toNode,WRITE_NORMAL);
		}								
	}

/** Writes the Node and it children to a file.
* @param node The node to start from
* @param file The name of the file to write to
* @param pretty Indicates whether to write pretty or normally (not implemented)
* @exception XMLException if the nodes could not be written to the file
*/
void Node::WriteToFile(Int32 node,String* fileName ,bool pretty)
		{
			if(pretty)
			{
				XmlWriteToFile(node,node,fileName,WRITE_PRETTY);
			}
			else
			{
				XmlWriteToFile(node,node,fileName,WRITE_NORMAL);
			}
		}


/** Writes a range of nodes to a file.
* @param from The node to start from
* @param to The node to continue to
* @param file The name of the file to write to
* @param pretty Indicates whether to write pretty or normally (not implemented)
* @exception XMLException if the nodes could not be written to the file
*/
void Node::WriteToFile(Int32 fromNode,Int32 toNode ,String* fileName ,bool pretty)
		{
			if(pretty)
			{
				XmlWriteToFile(fromNode,toNode,fileName,WRITE_PRETTY);
			}
			else
			{
				XmlWriteToFile(fromNode,toNode,fileName,WRITE_NORMAL);
			}
		}

/** Writes the contents of the node into the String that is returned
 *@param node That is to be written
 *@param pretty true for indentation false for writing as string
 */
String* Node::WriteToString(int node,bool pretty)
			{
				if(pretty)
				{
					return GetStrFromByteArray(XmlWriteToByteArray(node,node,WRITE_PRETTY));
				}
				else
				{
					return GetStrFromByteArray(XmlWriteToByteArray(node,node,WRITE_NORMAL));
				}
			}
